/*
*
* 版权所有 Copyleft(c) 2005
* 刘炯个人工作室 Sharp-Mark Personal Studio
*
* 允许自由使用，复制，修改，传播和贩卖此源程序及其文档，而不必支付任何费用。
* 以上的版权信息必须出现在每一份复制品中。同时这份版权信息和许可声明
* 也必须出现在支持文档中。刘炯个人工作室不对此软件适于那种具体
* 用途做出任何阐述。此代码只作为代码本身提供对其品质不做任何保证。
*
*/

static void MidPointCircle(int px, int py, int r, COLORREF color, CPaintDC& dc);
static void CirclePoints(int x, int y,	COLORREF color, CPaintDC& dc);
static void MidPointEllipse(int xc, int yc, int a, int b, COLORREF color, CPaintDC& dc);
static void EllipsePoints(int x, int y, COLORREF color, CPaintDC& dc);

static void MidPointCircle(int px, int py, int r, COLORREF color, CPaintDC& dc)
{
	int x, y;
	int e;

	x = 0;
	y = r;
	e = 1 - r;

	dc.OffsetViewportOrg(px, py);

	CirclePoints(x, y, color, dc);

	for (++x; x <= y; ++x)
	{
		if (e > 0)
		{
			e += 2 * (x - y) + 5;
			y--;
		}
		else
		{
			e += 2 * x + 3;
		}

		CirclePoints(x, y, color, dc);
	}

	dc.OffsetViewportOrg(-px, -py);
}

static void CirclePoints(int x, int y,	COLORREF color, CPaintDC& dc)
{
	dc.SetPixelV(x, y, color);
	dc.SetPixelV(y, x, color);
	dc.SetPixelV(-x, y, color);
	dc.SetPixelV(y, -x, color);
	dc.SetPixelV(x, -y, color);
	dc.SetPixelV(-y, x, color);
	dc.SetPixelV(-x, -y, color);
	dc.SetPixelV(-y, -x, color);
}

static void MidPointEllipse(int xc, int yc, int a, int b, COLORREF color, CPaintDC& dc)
{
	dc.OffsetViewportOrg(xc, yc);

	//int aa = a * a;
	//int bb = b * b;

	//int twoaa = 2 * aa;
	//int twobb = 2 * bb;

	int x = 0;
	int y = b;

	//int dx = 0;
	//int dy = twoaa * y;

	EllipsePoints(x, y, color, dc);

	//int e = b * b + a * a * ( -b + 0.25 );
	int e = int(b * b + a * a * ( -b + 0.25 ) + 0.5);

	while(2 * b * b * x <= 2 * a * a * y) {
		x++;

		if ( e > 0 )
		{
			e += b * b * ( 2 * x + 1 ) - 2 * a * a * ( y - 1 );
			y--;
		}
		else
		{
			e += b * b * ( 2 * x + 1 );
		}

		EllipsePoints(x, y, color, dc);

	} 

	e = int(b * b * (x + 0.5) * (x + 0.5) + a * a * (y - 1) * (y -1) - a * a * b * b + 0.5);

	while(y > 0) {
		y--;

		if ( e > 0 )
		{
			e += a * a * ( 2 * y + 1 ) - 2 * b * b * ( x - 1 );
			x++;
		}
		else
		{
			e += a * a * ( 2 * y + 1 );
		}

		EllipsePoints(x, y, color, dc);

	}
	dc.OffsetViewportOrg(-xc, -yc);

}

static void EllipsePoints(int x, int y, COLORREF color, CPaintDC& dc)
{
	dc.SetPixelV(x, y, color);
	dc.SetPixelV(-x, y, color);
	dc.SetPixelV(x, -y, color);
	dc.SetPixelV(-x, -y, color);
}